/* 服务端业务逻辑的核心代码 */
const qs = require('querystring')
// 导入路由
const handleUserRouter = require('./router/user')
const handleGoodsRouter = require('./router/goods')
const { readFile } = require('./utils/staticServer') // 导入读取静态资源的方法
const path = require('path')
const rootPath = path.join(__dirname, '../public')
const { SECRET } = require('./constants')
const { getRedis } = require('./db/redis')
const writeLog = require('./utils/log')
// 导入sync建表
require('./db/sync')

// 参数初始化
const initParams = (req) => {
  // 准备 请求方式 / 请求路径 / 请求参数
  // 1.处理请求方式
  req.method = req.method.toLowerCase()
  // 2.处理请求路径
  const urlArr = req.url.split('?')
  req.path = urlArr[0]
  // 3.处理请求参数
  return new Promise((resolve, reject) => { // 使用异步才能接收到req.body的参数
    if (req.method === 'get') {
      req.query = qs.parse(urlArr[1])
      resolve()
    } else if (req.method === 'post') {
      let params = ''
      req.on('data', chunk => {
        params += chunk
      })
      req.on('end', () => {
        req.body = qs.parse(params)
        resolve()
      })
    } else {
      reject(new Error(`服务端暂未配置${req.method}请求方式`))
    }
  })
}

// 设置Cookie过期时间
const getCookieExpires = () => {
  const date = new Date()
  date.setTime(date.getTime() + (1000 * 60 * 60 * 24))
  return date.toUTCString()
}
// 初始化cookie与session
const initCookieSession = async (req, res) => {
  // 1.处理Cookie
  req.cookie = {}
  if (req.headers.cookie) {
    req.headers.cookie.split(';').forEach((item) => {
      const keyValue = item.split('=')
      req.cookie[keyValue[0]] = keyValue[1]
    })
  }
  // 2.获取用户的唯一标识
  req.userId = req.cookie.userId
  if (!req.userId) {
    req.userId = `${Date.now()}_${Math.random()}_${SECRET}`
    // 给当前用户分配容器
    req.session = {}
    res.setHeader('Set-Cookie', `userId=${req.userId}; path=/; httpOnly; expires=${getCookieExpires()}`)
  }
  if (!req.session) {
    req.session = await getRedis(req.userId) || {}
  }
  console.log('服务端保存session', req.session)
}
// 返回成功响应 200 json数据
const setJsonEnd = (res, data) => {
  res.writeHead(200, 'success', { // 设置响应json格式与utf-8编码格式
    'Content-Type': 'application/json; charset=utf-8;'
  })
  res.end(JSON.stringify(data))
}
// 返回错误响应 404 没有匹配到任何路由
const setNotFoundEnd = (res) => {
  res.writeHead(404, '404 Not Found', {
    'Content-Type': 'text/plain'
  })
  res.end('404 Not Found')
}

// 服务端处理
const handleServer = async (req, res) => {
  // 查看环境变量
  console.log('环境变量:', process.env.NODE_ENV)
  // 日志记录与分析
  writeLog(`${req.method}--${req.url}--${req.headers['user-agent']}`)
  // 0.准备cookie和session
  await initCookieSession(req, res)
  // 1.加载静态资源并返回
  await readFile(req, res, rootPath)
  // 2.处理API请求
  res.setJsonEnd = setJsonEnd
  // 1.准备各种请求参数 method / path / query / body
  initParams(req).then(async () => {
    console.log('--------------------------')
    console.log('请求方式:', req.method)
    console.log('请求地址:', req.path)
    console.log('get请求参数:', req.query)
    console.log('post请求参数:', req.body)
    console.log('--------------------------')

    // 2.处理各种路由
    const userData = await handleUserRouter(req, res)
    // 2.1 处理用户相关路由
    if (userData) {
      res.setJsonEnd(res, userData)
      return
    }
    // 2.2 处理商品相关路由
    const goodsData = await handleGoodsRouter(req, res)
    if (goodsData) {
      res.setJsonEnd(res, goodsData)
      return
    }
    // 2.3 错误处理（没有匹配到任何路由）
    return setNotFoundEnd(res)
  })
}

module.exports = handleServer
